package com.mcxx.modules.tool.service;

import com.mcxx.common.exception.BizException;
import com.mcxx.modules.tool.service.impl.GuicaiExtremeService;
import com.mcxx.modules.tool.service.impl.GuicaiSubsistenceService;
import com.mcxx.modules.tool.service.impl.GuicaiTempAssService;
import com.mcxx.modules.base.service.read.AreaReadService;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayEntity;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayParam;
import com.mcxx.modules.miniSalvation.fundpay.service.read.FundPayReadService;
import com.mcxx.modules.system.dto.AreaMappingDTO;
import com.mcxx.modules.temporary.fundpay.entity.TmpFundPayEntity;
import com.mcxx.modules.temporary.fundpay.param.TmpFundPayParam;
import com.mcxx.modules.temporary.fundpay.service.read.TmpFundPayReadService;
import com.mcxx.result.BaseResult;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.DateUtil;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@TaTransactional
public class GenerateGuicaiService {

    @Autowired
    private FundPayReadService fundPayReadService;
    @Autowired
    private TmpFundPayReadService tmpFundPayReadService;
    @Autowired
    private GuicaiSubsistenceService guicaiSubsistenceService;
    @Autowired
    private GuicaiExtremeService guicaiExtremeService;
    @Autowired
    private GuicaiTempAssService guicaiTempAssService;
    @Autowired
    private AreaReadService areaReadService;

    private ExecutorService executorService = Executors.newFixedThreadPool(20);


    public BaseResult<Boolean> guicaiData(String strAreaCodes, String strMonths, String guicaiType, String id) {
        BaseResult<Boolean> result = new BaseResult<Boolean>();
        if(CommonUtil.invalidArgs(strMonths) || CommonUtil.invalidArgs(strAreaCodes) || CommonUtil.invalidArgs(guicaiType)) {
            throw new BizException(FailureCode.ERR_10000);
        }

        String[] areaCodes = strAreaCodes.split(",");
        for(String areaCode : areaCodes){

            List<AreaMappingDTO> areaCodeBycCodeALevle = areaReadService.getAreaCodeBycCodeALevle(areaCode);
            if(CollectionUtils.isNotEmpty(areaCodeBycCodeALevle)){

                Date date = DateUtil.str2Date(strMonths+"01", DateUtil.sdf6);
                String format = DateUtil.sdf2.format(date);

                for(AreaMappingDTO dto : areaCodeBycCodeALevle){
                    String queryAreaCode = dto.getAreaCode().substring(0, 6);

                    FundPayParam fp = new FundPayParam();
                    fp.setAreaCode(queryAreaCode);
                    fp.setStatus("1");
                    fp.setPayDate(strMonths+"01");
                    fp.setHouseholds(0);
                    if (guicaiType.indexOf("204") >= 0) {

                        fp.setBusinessCode(Constant.BusinessCode.DIBAO);
                        fp.setStandType("01");
                        fp.setPayType(Constant.FundType.CAPITAL_FUND_PAY);
                        List<FundPayEntity> citySalvArr = fundPayReadService.listAll(fp);


                        fp.setPayType(Constant.FundType.STAND_FUND_PAY);
                        List<FundPayEntity> standCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.ALLOWANCE_FUND_PAY);
                        List<FundPayEntity> allowanceCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.CUSTOM_FUND_PAY);
                        List<FundPayEntity> sustomCitySalvArr = fundPayReadService.listAll(fp);

                        if(CollectionUtils.isEmpty(citySalvArr)){
                            continue;
                        }
                        executorService.execute(new Runnable() {
                            @Override
                            public void run() {
                                guicaiSubsistenceService.findFamilyByPay(id,format,queryAreaCode,"204",
                                        citySalvArr,standCitySalvArr,allowanceCitySalvArr,sustomCitySalvArr);
                            }
                        });
                        //guicaiSubsistenceService.findFamilyByPay(queryAreaCode,"204",this.citySalvArr);
                    }
                    if (guicaiType.indexOf("205") >= 0) {

                        fp.setBusinessCode(Constant.BusinessCode.DIBAO);
                        fp.setStandType("02");
                        fp.setPayType(Constant.FundType.CAPITAL_FUND_PAY);
                        List<FundPayEntity> villSalvArr = fundPayReadService.listAll(fp);

                        fp.setPayType(Constant.FundType.STAND_FUND_PAY);
                        List<FundPayEntity> standCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.ALLOWANCE_FUND_PAY);
                        List<FundPayEntity> allowanceCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.CUSTOM_FUND_PAY);
                        List<FundPayEntity> sustomCitySalvArr = fundPayReadService.listAll(fp);

                        if(CollectionUtils.isEmpty(villSalvArr)){
                            continue;
                        }
                        executorService.execute(new Runnable() {
                            @Override
                            public void run() {
                                guicaiSubsistenceService.findFamilyByPay(id,format,queryAreaCode,"205",
                                        villSalvArr,standCitySalvArr,allowanceCitySalvArr,sustomCitySalvArr);
                            }
                        });
                        //guicaiSubsistenceService.findFamilyByPay(queryAreaCode,"205",this.villSalvArr);
                    }
                    if (guicaiType.indexOf("206") >= 0) {

                        fp.setBusinessCode(Constant.BusinessCode.TEKUN);
                        fp.setStandType("03");
                        fp.setPayType(Constant.FundType.CAPITAL_FUND_PAY);
                        List<FundPayEntity> cityPoorArr = fundPayReadService.listAll(fp);

                        fp.setPayType(Constant.FundType.STAND_FUND_PAY);
                        List<FundPayEntity> standCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.ALLOWANCE_FUND_PAY);
                        List<FundPayEntity> allowanceCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.CUSTOM_FUND_PAY);
                        List<FundPayEntity> sustomCitySalvArr = fundPayReadService.listAll(fp);

                        if(CollectionUtils.isNotEmpty(cityPoorArr)){

                            Map<String, List<FundPayEntity>> map = cityPoorArr.stream().collect(Collectors.groupingBy(FundPayEntity::getCostType));
                            executorService.execute(new Runnable() {
                                @Override
                                public void run() {
                                    guicaiExtremeService.findFamilyByPay(id,format,queryAreaCode,"206",
                                            map,standCitySalvArr,allowanceCitySalvArr,sustomCitySalvArr);
                                }
                            });
                        }

                    }
                    if (guicaiType.indexOf("207") >= 0) {

                        fp.setBusinessCode(Constant.BusinessCode.TEKUN);
                        fp.setStandType("04");
                        fp.setPayType(Constant.FundType.CAPITAL_FUND_PAY);
                        List<FundPayEntity> villPoorArr = fundPayReadService.listAll(fp);

                        fp.setPayType(Constant.FundType.STAND_FUND_PAY);
                        List<FundPayEntity> standCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.ALLOWANCE_FUND_PAY);
                        List<FundPayEntity> allowanceCitySalvArr = fundPayReadService.listAll(fp);
                        fp.setPayType(Constant.FundType.CUSTOM_FUND_PAY);
                        List<FundPayEntity> sustomCitySalvArr = fundPayReadService.listAll(fp);

                        if(CollectionUtils.isNotEmpty(villPoorArr)){
                            Map<String, List<FundPayEntity>> map = villPoorArr.stream().collect(Collectors.groupingBy(FundPayEntity::getCostType));
                            executorService.execute(new Runnable() {
                                @Override
                                public void run() {
                                    guicaiExtremeService.findFamilyByPay(id,format,queryAreaCode,"207",
                                            map,standCitySalvArr,allowanceCitySalvArr,sustomCitySalvArr);
                                }
                            });
                        }

                    }
                    if (guicaiType.indexOf("225") >= 0) {
                        TmpFundPayParam tp = new TmpFundPayParam();
                        tp.setAreaCode(queryAreaCode);
                        tp.setStatus("1");
                        tp.setPayDate(strMonths);
                        List<TmpFundPayEntity> tempArr = tmpFundPayReadService.getFundPayList(tp);
                        List<TmpFundPayEntity> tempArrNew = new ArrayList<>();
                        if(CollectionUtils.isEmpty(tempArr)){
                            continue;
                        }else{
                            Map<String, List<TmpFundPayEntity>> map = tempArr.stream().collect(Collectors.groupingBy(TmpFundPayEntity::getAreaCodeS));
                            tempArrNew.addAll(map.get(queryAreaCode+"000000"));
                        }

                        executorService.execute(new Runnable() {
                            @Override
                            public void run() {
                                guicaiTempAssService.findFamilyByPay(id,format,queryAreaCode, tempArrNew);
                            }
                        });
                        //guicaiTempAssService.findFamilyByPay(queryAreaCode,this.tempArr);
                    }
                }
            }
        }
        return null;
    }
}
